home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 January: Mac OS SDK / Dev.CD Jan 97 SDK1.toast / Development Kits (Disc 1) / QuickDraw GX / Programming Stuff / Sample Code / Printing Samples / Printer Drivers… / Generic LaserWriter / ChooserSupport.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-06-15  |  9.1 KB  |  318 lines  |  [TEXT/MPS ]

  1. /*
  2.     ChooserSupport.c - C code for PACK and LDEF resources used by the Chooser.
  3.     
  4.     6/14/96 - cn  - Updated to support Universal Interfaces 2.1.
  5.     8/28/94 - dmh - Finalized and universalized for the SDK.
  6.    12/18/93 - dmh - Updated for the b3 seed.  Fixed highlighting (BitClr) bug.
  7.     9/13/93 - dmh - Modified for the b2 seed.
  8.     4/26/93 - dmh - Modified for the b1 seed.
  9.     
  10.     Copyright © 1992-1994 Apple Computer, Inc.
  11.     All rights reserved.
  12. */
  13.  
  14. #include <Types.h>
  15. #include <QuickDraw.h>
  16. #include <Fonts.h>
  17. #include <Lists.h>
  18. #include <Devices.h>
  19. #include <Resources.h>
  20. #include <Script.h>
  21. #include <ToolUtils.h>
  22. #include <LowMem.h>
  23.  
  24. #include <GXGraphics.h>
  25. #include <GXPrinterDrivers.h>
  26.  
  27. // ------------------------------------------------------------------------
  28. // INTERNAL DEFINES
  29. // ------------------------------------------------------------------------
  30. // Chooser initialize message selector
  31. #define initializeMsg    11
  32.  
  33. // Icon Suite support
  34. #define ttNone        0x0000
  35. #define ttDisabled    0x0001
  36. #define    ttOffline    0x0002
  37. #define ttOpen        0x0003
  38. #define ttSelected     0x4000
  39. #define ttSelectedDisabled    (ttSelected + ttDisabled)
  40. #define ttSelectedOffline    (ttSelected + ttOffline)
  41. #define ttSelectedOpen        (ttSelected + ttOpen)
  42.  
  43. #define ttLabel0    0x0000
  44. #define ttLabel1    0x0100
  45. #define ttLabel2    0x0200
  46. #define ttLabel3    0x0300
  47. #define ttLabel4    0x0400
  48. #define ttLabel5    0x0500
  49. #define ttLabel6    0x0600
  50. #define ttLabel7    0x0700
  51. pascal OSErr PlotIconSuite(const Rect * theRect, short align, short iconTransform, Handle cIcon)
  52.     = {0x303C, 0x0603, 0xABC9};
  53.  
  54. // Copy of the DrawText trap
  55. pascal void OldDrawText(const void *textBuf,short firstByte,short byteCount)
  56.     = 0xA885; 
  57.  
  58. // ------------------------------------------------------------------------
  59. // MAIN CODE FOR PACK
  60. // ------------------------------------------------------------------------
  61. pascal OSErr Device(short message, short caller, StringPtr objName, 
  62.                     StringPtr zoneName, ListHandle theList, long p2)
  63. {
  64.     
  65.     OSErr            anErr = noErr;
  66.     extern Str31     gDriverName;
  67.     StringPtr        pDriverName = gDriverName;
  68.     extern gxJob    gJob;                        // Declared in our .a file.
  69.     gxJob            *pJob = &gJob;
  70.  
  71.     if (message == initializeMsg)    // InitializeMsg--start up GX
  72.     {
  73.         FCBPBRec    pb;
  74.  
  75.     /*
  76.         Get the name of our driver for GXHandleChooserMessage.
  77.         (The user may have renamed us.)
  78.     */
  79.         pb.ioCompletion     = nil;
  80.         pb.ioNamePtr         = pDriverName;
  81.         pb.ioVRefNum         = 0;
  82.         pb.ioRefNum         = CurResFile();
  83.         pb.ioFCBIndx         = 0;
  84.         anErr = PBGetFCBInfo(&pb, false);
  85.  
  86.     /*
  87.         Clear *pJob, because it hasn't been initialized yet.  That doesn't
  88.         happen until we pass GXHandleChooserMessage an initializeMsg.
  89.     */
  90.         *pJob = nil;
  91.  
  92.     /*
  93.         We need to initialize GX printing so that we can call
  94.         GXHandleChooserMessage.  Since printing requires a graphics
  95.         client, call GXEnterGraphics first.  If there are errors,
  96.         (for example, due to memory limitations), post an alert.
  97.     */
  98.         if (anErr == noErr)
  99.         {
  100.             GXEnterGraphics();
  101.             anErr = GXGetGraphicsError(nil);
  102.             if (anErr == noErr)
  103.             {
  104.                 anErr = GXInitPrinting();
  105.                 if (anErr != noErr)
  106.                     GXExitGraphics();
  107.             }
  108.                 
  109.             if (anErr != noErr)
  110.                 StopAlert(-4095, nil);
  111.         }
  112.     }
  113.  
  114. /*
  115.     If the Chooser hasn't created a job yet, do nothing unless we were
  116.     sent an initializeMsg.  In its default implementation of
  117.     GXHandleChooserMessage, QuickDraw GX will create the job for our
  118.     driver when it receives an initializeMsg.  It will store a reference
  119.     to it in our pJob pointer.
  120.     
  121.     For all other messages, if a job has been created, call
  122.     GXHandleChooserMessage to handle things.
  123. */
  124.     if (anErr == noErr)
  125.     {
  126.         if ((*pJob != nil) || (message == initializeMsg))
  127.         {
  128.             anErr = GXHandleChooserMessage(pJob, pDriverName, message, caller, objName, zoneName, theList, p2);
  129.     
  130.         /*
  131.             If we just got a terminateMsg, and p2 is also terminateMsg, the
  132.             Chooser is closing.  QuickDraw GX just disposed of the gxJob it
  133.             created earlier when GXHandleChooserMessage was passed
  134.             initializeMsg, so we just need to call GXExitPrinting and
  135.             GXExitGraphics to clean up.
  136.             
  137.             Note that we must test the p2 parameter, because the Chooser
  138.             can also send terminateMsg when it wants to empty the device
  139.             list, but not dispose of us.  For example, this will happen
  140.             when the user turns off AppleTalk in the Chooser.
  141.         */
  142.             if ((message == terminateMsg) && (p2 == terminateMsg))
  143.             {
  144.                 GXExitPrinting();
  145.                 GXExitGraphics();
  146.             }
  147.         }
  148.     }
  149.         
  150.     return(anErr);
  151.     
  152. } // Device
  153.  
  154.  
  155.  
  156. // ------------------------------------------------------------------------
  157. // ENTRY POINT FOR LDEF
  158. // ------------------------------------------------------------------------
  159.  
  160. pascal void LDEF(
  161.     short         message,        // What operation to perform on list
  162.     Boolean     select,            // Is this cell to be selected or not?
  163.     Rect        *theRect,        // Rectangle of this cell, clipped to window
  164.     Cell        theCell,        // Which cell this is
  165.     short        dataOffset,        // Offset into data for this cell
  166.     short        dataLen,        // Length of data for this cell
  167.     ListHandle    theList)        // The list to act upon
  168. /*
  169.     An LDEF that works in two modes:
  170.         - if the first two characters of the cell are valid AppleTalk NBP names (ie, not ≈ ≈)
  171.           then the LDEF is just a basic text LDEF
  172.         - otherwise, it assumes the data is part of a PortListRec, which is
  173.           a structure for icons with text underneath
  174. */
  175.  
  176. {
  177. #pragma unused (theCell, dataLen)
  178.  
  179.     gxPortListRec        theCellContents;
  180.     Rect                iconRect;
  181.     unsigned char        hiliteMode;
  182.     
  183.     switch (message)
  184.         {
  185.         case lDrawMsg:
  186.         case lHiliteMsg:
  187.         
  188.             // save the data to avoid locking things down
  189.             if (dataLen > sizeof(theCellContents) )
  190.                 dataLen = sizeof(theCellContents);
  191.             BlockMove(((*(**theList).cells) + dataOffset), &theCellContents, dataLen );
  192.             
  193.             // draw the cell as an icon, but only if we see our magic marker at the front
  194.             if ( (theCellContents.firstMarker == '≈') && (theCellContents.secondMarker == '≈') )
  195.                 {
  196.                 // center the icon rect on the list with a top margin of 10 pixels
  197.                 iconRect.top = theRect->top + 10;
  198.                 iconRect.left = theRect->left + ((theRect->right - theRect->left) >> 1) - 16;
  199.                 iconRect.bottom = iconRect.top + 32;
  200.                 iconRect.right = iconRect.left + 32;
  201.                 
  202.                 
  203.                 // draw the icon
  204.                 if (theCellContents.iconSuiteHandle != nil)
  205.                     PlotIconSuite(&iconRect,
  206.                             ttNone, (select) ? ttSelected: ttNone,
  207.                             theCellContents.iconSuiteHandle);
  208.                             
  209.                 // Get the general area under the icon in which to draw the label
  210.                 iconRect.left = theRect->left + 2;
  211.                 iconRect.right = iconRect.left + (**theList).cellSize.h - 2;
  212.                 iconRect.top = iconRect.bottom + 2;
  213.                 iconRect.bottom = theRect->bottom;
  214.     
  215.                 // use a nice small font for the label            
  216.                 TextFont(applFont);
  217.                 TextSize(9);
  218.                 
  219.                     {
  220.                     short        labelWidth;
  221.                     short        rectWidth;
  222.                     short        labelHeight;
  223.                     FontInfo    theInfo;
  224.                 
  225.                     // Get rid of any text that was there before
  226.                     EraseRect(&iconRect);
  227.                     iconRect.top += 2;
  228.                     
  229.                     // compute the height of the label                    
  230.                     GetFontInfo(&theInfo);
  231.                     labelHeight = theInfo.ascent + theInfo.leading;
  232.                     
  233.                     // compute where to draw the text
  234.                     iconRect.bottom = iconRect.top + labelHeight;
  235.                     rectWidth = iconRect.right-iconRect.left;
  236.                     
  237.                     // truncate the string to fit within the box
  238.                     TruncString(rectWidth, theCellContents.iconName, smTruncEnd);
  239.                     
  240.                     // compute the new width of the string
  241.                     labelWidth = StringWidth(theCellContents.iconName);
  242.                     
  243.                     // center the string, draw it
  244.                     iconRect.left += (rectWidth >> 1) - (labelWidth >> 1);
  245.                     MoveTo(iconRect.left, iconRect.bottom);
  246.                     DrawString(theCellContents.iconName);
  247.                     
  248.                     if (select)
  249.                         {
  250.                         // compute right and lower edge of box bounding the text we just drew
  251.                         iconRect.right = iconRect.left + labelWidth;
  252.                         iconRect.bottom += theInfo.descent;
  253.                         
  254.                         // outset it, and invert it to select it
  255.                         InsetRect(&iconRect, -1, -1);
  256.                         hiliteMode = LMGetHiliteMode();
  257.                         BitClr(&hiliteMode, pHiliteBit);
  258.                         LMSetHiliteMode(hiliteMode);
  259.                         InvertRect(&iconRect);
  260.                         }
  261.                     }
  262.                     
  263.                 TextFont(applFont);
  264.                 TextSize(0);
  265.                 }
  266.             else
  267.                 {
  268.                 // how boring!  It's only text
  269.                 FontInfo    theInfo;
  270.                 Rect        ourRect;
  271.                 short        cellWidth;
  272.                 
  273.                 // add a margin to the rectangle
  274.                 ourRect = *theRect;
  275.                 ourRect.left += 4;
  276.                 --ourRect.right;
  277.                 cellWidth = ourRect.right - ourRect.left;
  278.                 
  279.                 // erase the rectangle
  280.                 GetFontInfo(&theInfo);
  281.                 EraseRect(theRect);
  282.                 MoveTo(ourRect.left, ourRect.bottom - theInfo.descent);
  283.                 
  284.                 // hey, you can't park that string here -- it's too big!
  285.                 if (TextWidth((Ptr) &theCellContents, 0, dataLen) > cellWidth )
  286.                     {
  287.                     // condense the text first
  288.                     TextFace(condense);
  289.                     
  290.                     // then truncate afterwards
  291.                     TruncText(cellWidth, (Ptr) &theCellContents, &dataLen, smTruncEnd);
  292.                     }
  293.                     
  294.                 // those darn other languages!
  295.                 if (GetSysJust() == teJustRight)
  296.                     Move(cellWidth-TextWidth((Ptr) &theCellContents, 0, dataLen) , 0);
  297.                     
  298.                 OldDrawText((Ptr) &theCellContents, 0, dataLen);
  299.                 
  300.                 // if selected, invert it
  301.                 if (select)
  302.                     {
  303.                     hiliteMode = LMGetHiliteMode();
  304.                     BitClr(&hiliteMode, pHiliteBit);
  305.                     LMSetHiliteMode(hiliteMode);
  306.                     InvertRect(theRect);
  307.                     }
  308.                     
  309.                 // normal text again
  310.                 TextFace(normal);
  311.                 }
  312.                 
  313.             break;
  314.             
  315.         } // switch
  316.         
  317. } // LDEF
  318.